package me.shiqiang.im;

import com.aliyun.openservices.ons.api.bean.ProducerBean;
import me.shiqiang.im.config.RocketMqProducerConfig;
import me.shiqiang.im.enums.MessageCmd;
import me.shiqiang.im.listeners.ConnectServerListener;
import me.shiqiang.im.msg.Login;
import me.shiqiang.im.util.RedisPipelineProcessor;
import me.shiqiang.im.util.SnowFlake;
import io.socket.client.IO;
import io.socket.client.Socket;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;

import java.net.URISyntaxException;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * @author cuishiqiang
 * @date 2017/12/6 下午4:14
 */
@SpringCloudApplication
@EnableFeignClients
@EnableAutoConfiguration
@EnableScheduling
public class ImBusinessServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ImBusinessServerApplication.class, args);
    }

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Bean
    public ConcurrentLinkedQueue<RedisPipelineProcessor> createQueue() {
        return new ConcurrentLinkedQueue<>();
    }

    @Value("${machineId}")
    private String machineId;

    /*@Value("${server.id}")
    private String serverId;*/

    @Autowired
    Map<String, ConnectServerListener> connectionServerListeners;


    @Bean
    public SnowFlake createSnowFlake() {
        return new SnowFlake(Long.parseLong(machineId));
    }

    @Value("${connect.server.ip}")
    String serverIp;

    @Value("${connect.server.port}")
    String serverPort;

    @Bean(initMethod = "connect", destroyMethod = "disconnect")
    public Socket createSocketIOClient() throws URISyntaxException {
        logger.info("开始连接服务器connectServer:{}", serverIp);
        Socket socket = IO.socket(String.format("http://%s:%s/",serverIp,serverPort));
        socket.on(Socket.EVENT_CONNECT, (args) -> {   //注册为处理程序
            System.out.println("connected!");
            logger.info("已连接服务器connectServer:{}", serverIp);
            Login login = new Login();
            login.setProcessor(true);
            login.setUserId(1111111L);
            login.setPwd("processor");
            Object obj = JSONObject.wrap(login);
            socket.emit(MessageCmd.LOGIN, obj);
        });
        socket.on(Socket.EVENT_DISCONNECT, (args) -> System.out.println("disconnected!"));
        connectionServerListeners.values().forEach(emitListener -> {
            emitListener.setSocket(socket);
            socket.on(emitListener.eventName(), emitListener);
        });
        logger.info("machineId={}", machineId);
        return socket;
    }


//    @Value("${connect.routeServer.ip}")
//    String routerServerIp;
//
//    @Value("${connect.routeServer.port}")
//    String routeServerPort;

//    @Autowired
//    RouterServerNodeClient client;
//
//    @Bean(name = "routerServerClient",initMethod = "connect", destroyMethod = "disconnect")
//    public Socket createRouterSocketClient() throws URISyntaxException {
//        Collection<String> addresses=client.getAllRouterIps();
//        Map<String,Socket> socketMap=new HashMap<>();
//        for(String address:addresses){
//            address=address.replaceAll("_","\\.").replaceAll("@",":");
//            Socket socket = IO.socket(String.format("http://%s/",address));
//            socket.on(Socket.EVENT_CONNECT, (args) -> {   //注册为处理程序
//                System.out.println("connected!");
//                Login login = new Login();
//                login.setProcessor(true);
//                login.setUserId(Long.parseLong(serverId));
//                login.setPwd("processor");
//                Object obj = JSONObject.wrap(login);
//                socket.emit(MessageCmd.LOGIN, obj);
//            });
//            socket.on(Socket.EVENT_DISCONNECT, (args) -> System.out.println("disconnected!"));
//            routerServerListeners.values().forEach(emitListener -> {
//                socket.on(emitListener.eventName(), emitListener);
//            });
//            logger.info("machineId={}", machineId);
//            socketMap.put(address,socket);
//        }
//
//        return socketMap.values().iterator().next();
//    }


    @Bean(initMethod = "start", destroyMethod = "shutdown")
    public ProducerBean createProducerBean(RocketMqProducerConfig config) {
        ProducerBean producerBean = new ProducerBean();
        producerBean.setProperties(config.getProperties());
        return producerBean;
    }

//    @Autowired
//    private Map<String,MessageListener> consumerMap;
//
//    @Value("#{${com.tst.rocketmq.consumer.subscription}}")
//    Map<String, String> consumerSubscription;
//
//
//    @Bean(initMethod = "start", destroyMethod = "shutdown")
//    public ConsumerBean createConsumerBean(RocketMqConsumerConfig config) {
//        ConsumerBean consumerBean = new ConsumerBean();
//        consumerBean.setProperties(config.getProperties());
//        Map<Subscription, MessageListener> table = new HashMap<>();
//        for (Map.Entry<String, String> consumerConfig : consumerSubscription.entrySet()) {
//            if (consumerMap.containsKey(consumerConfig.getKey())) {
//                MessageListener messageListener = consumerMap.get(consumerConfig.getKey());
//                String[] configs = consumerConfig.getValue().split("#");
//                Subscription subscription = new Subscription();
//                subscription.setTopic(configs[0]);
//                subscription.setExpression(configs[1]);
//                table.put(subscription, messageListener);
//            }
//        }
//        consumerBean.setSubscriptionTable(table);
//        return consumerBean;
//    }

}
